//享元模式，flyweight,运用共享技术创建大量细粒度的对象
//优点：相同对象只需要保存一份，降低了系统中对象的数量，从而讲了了细粒度
//对系统造成的压力
//缺点：为了实现共享，需要将不能共享的状态外部化，这将增加系统的复杂度
#include <iostream>
#include <memory>
#include <string>
#include <map>
//非享元部分，用于区分不同的对象，相当于外部信息
class User
{
public:
    using ptr=std::shared_ptr<User>;
    User(const std::string& name):m_name(name){}
    std::string getName() const {return m_name;}
private:
    std::string m_name;
};
//享元部分，多个对象相同的部分
class Website
{
public:
    using ptr=std::shared_ptr<Website>;
    virtual void use(const User& user)=0;
};

class ConcreteWebsite:public Website
{
public:
    using ptr=std::shared_ptr<ConcreteWebsite>;
    ConcreteWebsite(const std::string& name):m_name(name){}
    void use(const User& user) override 
    {
        std::cout<<"网站分类:"<<this->m_name<<"\t网站用户:"<<user.getName()<<std::endl;
    }
private:
    std::string m_name;
};

class WebFactory
{
public:
    using ptr=std::shared_ptr<WebFactory>;
    Website::ptr createWeb(const std::string& name)
    {
        if (m_webMap.find(name)!=m_webMap.end()){
            return m_webMap[name];
        }
        Website::ptr web(new ConcreteWebsite(name));
        m_webMap.insert(std::make_pair(name,web));
        return web;
    }
    int getSize() const
    {
        return m_webMap.size();
    }
private:
    std::map<std::string,Website::ptr> m_webMap;
};

int main(int argc, char** argv)
{
    WebFactory::ptr wf(new WebFactory);
    Website::ptr fx=wf->createWeb("产品展示");
    fx->use(User("小菜"));
    Website::ptr fy=wf->createWeb("产品展示");
    fy->use(User("大鸟"));
    Website::ptr fz=wf->createWeb("产品展示");
    fz->use(User("娇娇"));
    Website::ptr fa=wf->createWeb("个人博客");
    fa->use(User("黄蓉"));
    Website::ptr fb=wf->createWeb("个人博客");
    fb->use(User("郭靖"));
    Website::ptr fc=wf->createWeb("个人博客");
    fc->use(User("令狐冲"));
    std::cout<<"共创建了"<<wf->getSize()<<"个实例";
    return 0;
}